package com.study.easyexcel.api.converter;

import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.MapUtils;
import com.study.easyexcel.api.annotation.ConverterConfiguration;
import com.study.easyexcel.common.domain.CustomType;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 自定义类型转换器，数据可来源于数据库；但无法通过注解直接使用，可以注册全局转换器+{@link ConverterConfiguration}的
 * 结合来实现注解标记字段
 *
 * @author yuhuan
 * @date 2023/10/26
 */
public class CustomConverter implements FlexibleConverter<String> {

    private final Map<String, List<CustomType>> customTypes = MapUtils.newHashMap();

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    public CustomConverter(Map<String, List<CustomType>> converterMap) {
        if (ObjectUtils.isEmpty(converterMap)) {
            return;
        }
        this.customTypes.putAll(converterMap);
    }

    public CustomConverter(String key, List<CustomType> typeList) {
        this.customTypes.put(key, typeList);
    }

    @Override
    public String convertToJavaData(ReadConverterContext<?> context) throws Exception {
        Field field = context.getContentProperty().getField();
        String val = context.getReadCellData().getStringValue();
        if (checkFieldBusinessConverter(field)) {
            ConverterConfiguration converterConfiguration = field.getAnnotation(ConverterConfiguration.class);
            String key = converterConfiguration.value();
            List<CustomType> typeList = customTypes.get(key);
            Optional<CustomType> ct = typeList.stream().filter(customType -> customType.getName().equals(val)).findFirst();
            return ct.orElseGet(CustomType::new).getCode();
        } else {
            return val;
        }
    }

    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) throws Exception {
        Field field = context.getContentProperty().getField();
        String val = context.getValue();
        if (checkFieldBusinessConverter(field)) {
            ConverterConfiguration converterConfiguration = field.getAnnotation(ConverterConfiguration.class);
            String key = converterConfiguration.value();
            List<CustomType> typeList = customTypes.get(key);
            Optional<CustomType> ct = typeList.stream().filter(customType -> customType.getCode().equals(val)).findFirst();
            return new WriteCellData<>(ct.orElseGet(CustomType::new).getName());
        } else {
            return new WriteCellData<>(val);
        }
    }
}
